﻿using System;
using System.Runtime.InteropServices;

namespace CabConfigProvisioning
{
    internal class FciGenericCallbacks
    {
        public static IntPtr FileOpen(string sFilePath, int oflag, int pmode, ref int nError, IntPtr userData)
        {
            IFciActions actions = (IFciActions) ((GCHandle) userData).Target;
            return actions.FileOpen(sFilePath, oflag, pmode, ref nError);
        }

        public static int FileClose(IntPtr hFile, ref int nError, IntPtr userData)
        {
            IFciActions actions = (IFciActions)((GCHandle)userData).Target;
            return actions.FileClose(hFile, ref nError);
        }

        public static int FileRead(IntPtr hFile, byte[] buf, int nSize, ref int nError, IntPtr userData)
        {
            IFciActions actions = (IFciActions)((GCHandle)userData).Target;
            return actions.FileRead(hFile, buf, nSize, ref nError);
        }

        public static int FileWrite(IntPtr hFile, byte[] buf, int nSize, ref int nError, IntPtr userData)
        {
            IFciActions actions = (IFciActions)((GCHandle)userData).Target;
            return actions.FileWrite(hFile, buf, nSize, ref nError);
        }

        public static int FileSeek(IntPtr hFile, int nOfs, int nDirection, ref int nError, IntPtr userData)
        {
            IFciActions actions = (IFciActions)((GCHandle)userData).Target;
            return actions.FileSeek(hFile, nOfs, nDirection, ref nError);
        }

        public static int FilePlaced(ref FciCabinetInfo cabinfo, string sFilePath, int cbFile, bool bContinuation, IntPtr userData)
        {
            IFciActions actions = (IFciActions)((GCHandle)userData).Target;
            return actions.FilePlaced(ref cabinfo, sFilePath, cbFile, bContinuation);
        }

        public static int FileDelete(string sFilePath, ref int nError, IntPtr userData)
        {
            IFciActions actions = (IFciActions)((GCHandle)userData).Target;
            return actions.FileDelete(sFilePath, ref nError);
        }

        public static bool GetTempFile(char[] sTempFilePath, int nTempPathSize, IntPtr userData)
        {
            IFciActions actions = (IFciActions)((GCHandle)userData).Target;
            return actions.GetTempFile(sTempFilePath, nTempPathSize);
        }

        public static bool GetNextCabinet(ref FciCabinetInfo cabinfo, ulong cbprevcab, IntPtr userData)
        {
            IFciActions actions = (IFciActions)((GCHandle)userData).Target;
            return actions.GetNextCabinet(ref cabinfo, cbprevcab);
        }

        public static int Status(uint typestatus, uint cb1, uint cb2, IntPtr userData)
        {
            IFciActions actions = (IFciActions)((GCHandle)userData).Target;
            return actions.Status(typestatus, cb1, cb2);
        }

        public static IntPtr GetOpenInfo(string pszname, out ushort pdate, out ushort ptime, out ushort pattribs, ref int nError, IntPtr userData)
        {
            IFciActions actions = (IFciActions)((GCHandle)userData).Target;
            return actions.GetOpenInfo(pszname, out pdate, out ptime, out pattribs, ref nError);
        }

        public static IntPtr MemAlloc(int cb)
        {
            return Marshal.AllocHGlobal(cb);
        }

        public static void MemFree(IntPtr mem)
        {
            Marshal.FreeHGlobal(mem);
        }

    }
}
